package com.ptswitch.material.service.impl;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.hibernate.Hibernate;
import org.hxzon.project.AbstractModelService;
import org.hxzon.util.MD5Util;
import org.hxzon.util.cache.FifoCache;
import org.springframework.stereotype.Service;

import com.ptswitch.material.model.common.Uzer;
import com.ptswitch.material.service.UserService;
import com.ptswitch.material.util.security.RoleUtil;

@Service
public class UserServiceImpl extends AbstractModelService<Uzer> implements UserService {
    private FifoCache<String, Uzer> userCache = new FifoCache<String, Uzer>(100);

    @Override
    public void initUsers() {
        long count = dao.countList(Uzer.class);
        if (count == 0) {
            Uzer admin = new Uzer("admin", "admin", "超级管理员", Uzer.Department_Software);
            admin.md5password();
            admin.addRole(RoleUtil.Admin);
            //
            Uzer buyer = new Uzer("buyer1", "buyer1", "采购员1", Uzer.Department_Buyer);
            buyer.addRole(RoleUtil.DepartmentBuyer);
            buyer.md5password();
            //
            Uzer financial = new Uzer("financial1", "financial1", "财务员1", Uzer.Department_Financial);
            financial.addRole(RoleUtil.DepartmentFinancial);
            financial.md5password();
            //
            Uzer production = new Uzer("production1", "production1", "生产员1", Uzer.Department_Production);
            production.addRole(RoleUtil.DepartmentProduction);
            production.md5password();
            //
            Uzer auditor = new Uzer("auditor1", "auditor1", "采购审核员1", Uzer.Department_ContractAuditor);
            auditor.md5password();
            //
            dao.addAll(Arrays.asList(admin, buyer, financial, production, auditor));
        }
    }

    //
    @Override
    public long countLikeByUsername(String username) {
        return dao.countList(Uzer.class, "where p.username like :username",//
                "username", ("%" + username + "%"));
    }

    @Override
    public List<Uzer> likeByUsername(String username, long first, long size) {
        return dao.list(Uzer.class, //
                "where p.username like :username order by p.username asc", first, size,//
                "username", ("%" + username + "%"));
    }

    //

    @Override
    public void save(Uzer user) {
        super.save(user);
        //userCache.add(user.getUsername(), user);
    }

    @Override
    public void saveAll(Collection<Uzer> users) {
        for (Uzer user : users) {
            save(user);
        }
    }

    @Override
    public void delete(Uzer user) {
        super.delete(user);
        userCache.remove(user.getUsername());
    }

    @Override
    public Uzer findById(long id) {
        Uzer result = super.findById(id);
        if (result != null) {
            Hibernate.initialize(result.getUserRoles());
            //userCache.add(result.getUsername(), result);
        }
        return result;
    }

    @Override
    public Uzer findByUsername(String username) {
        if (username == null || username.isEmpty()) {
            return null;
        }
        if (Uzer.Username_Guess.equals(username)) {
            return null;//return null not return new Uzer()
        }
        Uzer result = userCache.get(username);
        if (result != null) {
            return result;
        }
        result = dao.one(Uzer.class, " where p.username=:username", "username", username);
        if (result != null) {
            Hibernate.initialize(result.getUserRoles());
            //userCache.add(result.getUsername(), result);
        }
        return result;
    }

    @Override
    public Uzer findByUsernameAndPassword(String username, String password) {
        if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
            return null;
        }
        if (password.length() < 32) {
            password = MD5Util.toMD5(username + password);
        }
        Uzer result = findByUsername(username);
        if (result != null) {
            if (password.equals(result.getPassword())) {
                return result;
            }
        }
        return null;
    }

    @Override
    public List<Uzer> findByDepartment(int department) {
        return dao.list(Uzer.class, " where p.department=:department ", //
                -1, -1, "department", department);
    }

    @Override
    public boolean existUsername(String username) {
        return (findByUsername(username) != null);
    }

}
